/**
  client.h - Created by Timothy Morey on 4/5/2012.

  Defines a simple interface that can be used to send a buffer of data to a 
  server through a TCP socket.
*/

#ifndef __CLIENT_H
#define __CLIENT_H

#include "libnvn.h"

#ifdef __cplusplus
extern "C"
{
#endif

/**
  A client is a component that can connect to, send data to, and receive a 
  response from a server.
*/
typedef struct
{
  char ServerName[64];  // The name that identifies the server on the network

  char Port[8];         // The server port that the server listens to

  int Async;            // Indicates if client operations are performed
                        // synchronously.  If this is true, the client will
                        // manage a background thread that will be used for all
                        // network communications.

} Client;

/**
  Creates a new synchronous client and connects it to the specified server.

  @param[in] server The server address.
  @param[in] port The port the server listens on.
  @param[out] client A pointer to the newly constructed client, or 0 if an
  error occurs.

  @return An nvn error code indicating if the operation was successful.
*/
EXPORT int ConnectClient(const char* server, const char* port, Client** client);

/**
  Creates a new asynchronous client and connects it to the specified server.

  @param[in] server The server address.
  @param[in] port The port the server listens on.
  @param[out] client A pointer to the newly constructed client, or 0 if an
  error occurs.

  @return An nvn error code indicating if the operation was successful.
*/
EXPORT int ConnectAsyncClient(const char* server, const char* port, Client** client);

/**
  Destroys a client previously created with a call to ConnectClient or 
  ConnectAsyncClient.  This operation is always performed synchronously -- if
  it is an aysnc client, this function will block until the client thread
  terminates.

  @param[in] client The client that will be destroyed.

  @return An nvn error code indicating if the operation was successful.
*/
EXPORT int DestroyClient(Client* client);

/**
  Sends a short message to the specified server, which is expected to be running
  the server.h/server.c server code, and waits for confirmation to find out if
  there is a server available at the specified address.

  @param[in] addr The address of the server.
  @param[in] port The port at which the server is listening.

  @return An nvn error code indicating if the operation was sucessful.  If no
  error is reported, then we successfully ping'd the server.
*/
EXPORT int PingServer(const char* addr, const char* port);

/**
  Sends a message to the server but does not wait for a response.  If client is
  an async client, then this function may return before the message actually 
  gets sent.

  @param[in] client The client that we will use to send the data.
  @param[in] buf A data buffer that is at least len bytes long.
  @param[in] len Then number of bytes in buf that we will send.

  @return An nvn error code indicating if the operation was successful.
*/
EXPORT int Send(Client* client, const char* buf, int len);

/**
  Sends a message to the server and then waits for a response.  This function
  will behave synchronously regardless of whether client is async, as it will
  block until a response is received.

  @param[in] client The client that we will use to send the data.
  @param[in] sendBuf A data buffer that is at least sendLen bytes long and contains
  the data we will send.
  @param[in] sendLen Then number of bytes in sendBuf that we will send.
  @param[in,out] recvBuf A data buffer that is at least *recvLen bytes long and will be
  used to store the response from the server.
  @param[in,out] recvLen A pointer to the number of available bytes in recvBuf, which 
  will be updated to indicate the number of bytes that are part of the response.

  @return An nvn error code indicating if the operation was successful.
*/
EXPORT int SendAndReceive(Client* client, 
                          const char* sendBuf, int sendLen, 
                          char* recvBuf, int* recvLen);

#ifdef __cplusplus
}
#endif

#endif
